package com.zxshhy.controller;

import com.zxshhy.service.OrderService;
import com.zxshhy.util.RedisUtils;
import com.zxshhy.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author zxs
 */
@RefreshScope
@RestController
@RequestMapping("/redis/order")
@Slf4j
public class OrderRedisController {

    @Value("${spring.redis.host}")
    private String redisHost;
    @Value("${spring.redis.port}")
    private Integer redisport;
    @Resource
    private OrderService orderService;
    @Resource
    private RedisUtils redisUtils;

    /**
     * 秒杀代码
     *
     * @return
     */
    @GetMapping("/killOrderByRedis")
    public ResultVo killOrderByRedis() {
        log.info("开始秒杀");
        String redisKey = "lock";
        ExecutorService executorService = Executors.newFixedThreadPool(20);//20个线程
        try {//初始化
            Jedis jedis = new Jedis(redisHost, redisport);
            jedis.auth("longse");
            jedis.select(15);
            // 初始值
            jedis.set(redisKey, "0");
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 1000; i++) {//尝试1000次
            executorService.execute(() -> {
                Jedis jedis1 = new Jedis(redisHost, redisport);
                jedis1.auth("longse");
                jedis1.select(15);
                try {
                    jedis1.watch(redisKey);
                    String redisValue = jedis1.get(redisKey);
                    int valInteger = Integer.valueOf(redisValue);
                    String userInfo = UUID.randomUUID().toString();
                    // 没有秒完
                    if (valInteger < 20) {//redisKey
                        System.out.println("满足抢秒杀用户：" + valInteger);;
                        Transaction tx = jedis1.multi();//开启事务
                        tx.incr(redisKey);//自增
                        List list = tx.exec();//提交事务，如果返回nil则说明执行失败，因为我watch了的，只要执行失败，则
                        // 进来发现东西还有，秒杀成功
                        if (list != null && list.size() > 0) {
                            System.out.println("用户：" + userInfo + "，秒杀成功！当前成功人数：" + (valInteger + 1));
                        } else {//执行结果不是OK，说明被修改了，被别人抢了
                            System.out.println("用户：" + userInfo + "，秒杀失败");
                        }
                    } else {//东西秒完了
                        System.out.println("已经有20人秒杀成功，秒杀结束");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {//关闭redis
                    jedis1.close();
                }
            });
        }
        executorService.shutdown();//关闭线程池
        log.info("秒杀结束");
        return ResultVo.ok("秒杀结束");
    }

}
